from tqsdk import TqApi, TqAuth, TqKq
from tqsdk.ta import MACD
import time

def macd_strategy():
    # 创建天勤API实例(使用快期模拟账户)
    api = TqApi(auth=TqAuth("cps168", "alibaba999"), account=TqKq())
    
    # 获取K线数据(这里以螺纹钢主力合约为例)
    klines = api.get_kline_serial("SHFE.rb2505", 900,300)  # 15分钟K线
    
    # 持仓变量
    position = None
    
    try:
        while True:
            # 同步等待K线更新
            deadline = time.time() + 1
            api.wait_update(deadline=deadline)
            
            # 确保有足够K线数据
            if len(klines.close) < 35:  # MACD(12,26,9)至少需要35根K线
                print("等待K线数据积累...")
                continue
                
            try:
                # 计算MACD指标
                macd_data = MACD(klines, 12, 26, 9)
                
                # 获取最新MACD值
                dif = macd_data["dif"][-1]
                dea = macd_data["dea"][-1]
                prev_dif = macd_data["dif"][-2]
                prev_dea = macd_data["dea"][-2]
            #except KeyError:
            except Exception as e:
                print(f"KeyError: {e}")
                print("MACD计算失败，等待下一周期...")
                continue
            
            # 金叉条件: DIF上穿DEA
            golden_cross = prev_dif <= prev_dea and dif > dea
            
            # 死叉条件: DIF下穿DEA
            dead_cross = prev_dif >= prev_dea and dif < dea
            
            # 获取当前持仓
            position = api.get_position("SHFE.rb2405")
            
            # 交易逻辑
            if golden_cross and (position is None or position.pos == 0):
                print("出现金叉信号，开多仓")
                api.insert_order(symbol="SHFE.rb2405", direction="BUY", offset="OPEN", volume=1)
                
            elif dead_cross and (position is not None and position.pos > 0):
                print("出现死叉信号，平多仓")
                api.insert_order(symbol="SHFE.rb2405", direction="SELL", offset="CLOSE", volume=1)
                
    finally:
        # 确保API连接被关闭
        api.close()

if __name__ == "__main__":
    # 运行策略
    macd_strategy()